package com.vibrationkeyboard.app.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import kotlin.math.sqrt

@Parcelize
data class SensorData(
    val x: Float,
    val y: Float,
    val z: Float,
    val timestamp: Long = System.currentTimeMillis()
) : Parcelable {
    
    val magnitude: Float
        get() = sqrt(x * x + y * y + z * z)
    
    val normalized: SensorData
        get() {
            val mag = magnitude
            return if (mag > 0) {
                SensorData(x / mag, y / mag, z / mag, timestamp)
            } else {
                this
            }
        }
    
    operator fun plus(other: SensorData): SensorData {
        return SensorData(x + other.x, y + other.y, z + other.z, timestamp)
    }
    
    operator fun minus(other: SensorData): SensorData {
        return SensorData(x - other.x, y - other.y, z - other.z, timestamp)
    }
    
    operator fun times(scalar: Float): SensorData {
        return SensorData(x * scalar, y * scalar, z * scalar, timestamp)
    }
    
    fun distance(other: SensorData): Float {
        val dx = x - other.x
        val dy = y - other.y
        val dz = z - other.z
        return sqrt(dx * dx + dy * dy + dz * dz)
    }
    
    fun dot(other: SensorData): Float {
        return x * other.x + y * other.y + z * other.z
    }
    
    fun cross(other: SensorData): SensorData {
        return SensorData(
            y * other.z - z * other.y,
            z * other.x - x * other.z,
            x * other.y - y * other.x,
            timestamp
        )
    }
    
    override fun toString(): String {
        return "SensorData(x=%.3f, y=%.3f, z=%.3f, mag=%.3f)".format(x, y, z, magnitude)
    }
    
    companion object {
        fun zero(): SensorData = SensorData(0f, 0f, 0f)
        
        fun fromArray(array: FloatArray): SensorData {
            return when (array.size) {
                3 -> SensorData(array[0], array[1], array[2])
                2 -> SensorData(array[0], array[1], 0f)
                1 -> SensorData(array[0], 0f, 0f)
                else -> zero()
            }
        }
    }
} 